/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package diskfilesystem;

/**
 *
 * @author Administrator
 */
public class Disk {

    public final int OK = 0;
    public final int ERROR = -1;
    public final int BLOCK_NUM = 128;
    public final int BLOCK_LENGTH = 64;
    public char[][] block = new char[BLOCK_NUM][BLOCK_LENGTH];

    public Disk() {
        //block = new char[BLOCK_NUM][BLOCK_LENGTH];
        for (int i = 0; i < 2; i++) {                       //第0,1块为文件分配表，初始化
            for (int j = 0; j < BLOCK_LENGTH; j++) {
                block[i][j] = 0;
            }
        }
        for (int i = 2; i < BLOCK_NUM; i++) {                       //第0,1块为文件分配表，初始化
            for (int j = 0; j < BLOCK_LENGTH; j++) {
                block[i][j] = ' ';
            }
        }
        block[0][0] = block[0][1] = block[0][2] = 255;
    }

    public void createFile(Document f) {
        int k = find0after(2);
        block[k / BLOCK_LENGTH][k % BLOCK_LENGTH] = 255;    //初始创建文件只分配一个盘块
        int l = f.getName().length();
        if (l > 6 || l < 3) {
            System.out.print("文件名的长度应大于等于3或小于等于6");
        } else {
            for (int i = 0; i < l - 2; i++) {
                block[k][i] = f.name[i] = f.getName().charAt(i);
            }
            block[k][4] = f.extendName = f.getName().charAt(l - 1);
            block[k][5] = f.attribute = 'w';
            block[k][6] = f.begin = (char) k;///////////////////////////////////////////////////////////////////////////////
            block[k][7] = f.size = 1;
            //System.out.println(0+f.begin+" "+ (0+(char)k));
            //String s=f.read();
            //for(int j=0;j<s.length();j++){
            //    block[k][j]=s.charAt(j);
            //}
        }
    }

    public void deleteFile(Document f) {
        //this.showFileInfo(f);
        int n = 0 + (int) f.begin;    //起始盘块号
        int i = n / BLOCK_LENGTH;
        int j = n % BLOCK_LENGTH;
        //System.out.println(0+f.begin+" "+ n+" "+i+" "+j);
        int next = block[i][j];                   //文件占用的下一个盘块号
        for (int x = 0; x < BLOCK_LENGTH; x++) {
            block[n][x] = ' ';                      //释放文件占用的盘块
        }
        while (next != 255) {
            block[i][j] = 0;
            for (int x = 0; x < BLOCK_LENGTH; x++) {
                block[next][x] = ' ';
            }
            i = next / BLOCK_LENGTH;
            j = next % BLOCK_LENGTH;
            next = block[i][j];
        }
        //System.out.println(0+f.begin+" "+ n+" "+i+" "+j);
        block[i][j] = 0;
    }

    public int createDirectory(Document f) {
        int k = find0after(2);
        block[k / BLOCK_LENGTH][k % BLOCK_LENGTH] = 255;    //目录只分配一个盘块，记录在目录项的起始盘块
        //只需查到该新建目录的父目录，若父目录已满8个子目录则无法新建目录，否则直接在父目录所在块添加该新建目录的目录项即可
        int l = f.getName().length();
        //System.out.println(f.getName());
        if (l > 4) {
            System.out.print("文件夹名称的长度应小于或等于4");
        } else {
            int i = this.findParent(f);             //i为父目录所占用的盘块，即起始盘块
            if (this.saveFileInfo(f, i, k) == OK) {
                f.size=1;
                return OK;
            }
        }
        return ERROR;
    }

    public int deleteDirectory(Document f) {
        int n = 0 + f.begin;    //起始盘块号
        if (block[n][0] != ' ') {
            System.out.print("不能删除非空目录");
            return ERROR;
        }
        block[n / BLOCK_LENGTH][n % BLOCK_LENGTH] = 0;
        int i = this.findParent(f);
        int j;
        for (int q = 0; q < BLOCK_LENGTH; q += 8) {
            for (j = 0; j < f.getName().length(); j++) {
                if (block[i][q + j] != f.getName().charAt(j)) {
                    break;
                }
            }
            if (j >= f.getName().length()) {
                for (j = 0; j < 8; j++) {
                    block[i][q + j] = ' ';
                }
            }
        }
        System.out.println(n + " " + i);
        return OK;
    }

    public int rename(Document f) {
        if (this.saveFileInfo(f, this.findParent(f)) == OK) {
            return OK;
        }
        return ERROR;
    }

    public int saveFileInfo(Document f, int parent) {       //修改文件名称时使用，保存信息到原块
        int i = parent;
        if (i == ERROR) {
            System.out.println("路径名错误");
            return ERROR;
        }
        for (int p = 0; p < BLOCK_LENGTH; p += 8) {
            if (block[i][p] == ' ') {
                for (int x = 0; x < f.getName().length(); x++) {
                    block[i][p + x] = f.name[x] = f.getName().charAt(x);
                    //System.out.println(f.getName()+"   "+i+"   "+(p+x)+"  "+x+"    "+block[i][p + x]);
                }
                //System.out.println(0 + f.begin + " " + k);
                return OK;
            }
        }
        return ERROR;           //已扫描过父目录，其子目录已满8个，返回错误，值为-1
    }

    public int saveFileInfo(Document f, int parent, int block_id) {         //创建文件时使用，保存信息到空闲块
        int i = parent;
        int k = block_id;
        if (i == ERROR) {
            System.out.println("路径名错误");
            return ERROR;
        }
        for (int p = 0; p < BLOCK_LENGTH; p += 8) {
            if (block[i][p] == ' ') {
                for (int x = 0; x < f.getName().length(); x++) {
                    block[i][p + x] = f.name[x] = f.getName().charAt(x);
                    //System.out.println(f.getName()+"   "+i+"   "+(p+x)+"    "+block[i][p + x]);
                }
                block[i][p + 4] = f.extendName = ' ';
                block[i][p + 5] = f.attribute = 'm';
                block[i][p + 6] = f.begin = (char) (k);
                block[i][p + 7] = 0;
                //System.out.println(0 + f.begin + " " + k);
                return OK;
            }
        }
        return ERROR;           //已扫描过父目录，其子目录已满8个，返回错误，值为-1
    }

    public int findParent(Document f) {
        String path = f.getParent();        //这里获取的路径为C\***\***
        //System.out.println(path);
        String t[] = path.split("\\\\");
        if (t.length == 1) {
            return 2;
        }
        int m = 1;                            //根目录已知，所以从第二个目录文件查起
        int j;
        int i = 2;
        for (int q = 0; q < BLOCK_LENGTH; q += 8) {
            for (j = 0; j < t[m].length(); j++) {
                //System.out.println(t[m]);
                if (t[m].charAt(j) != block[i][q + j]) {
                    //System.out.println(i+"  "+ (q+j)+"123"+block[i][q + j]+"1   "+t[m].charAt(j));
                    break;
                }
            }
            if (j >= t[m].length()) {
                if (m == t.length - 1) {        //已匹配到路径名的最后一个父目录名称
                    return i;           //i此时为最后一个父目录所在的盘块号
                }
                m++;
                i = block[i][q + 6];
            }
        }
        return ERROR;
    }

    public int find0after(int n) {       //从第n块起，在文件分配表中找空闲块，共128块
        int i = n / BLOCK_LENGTH;
        int j = n % BLOCK_LENGTH;
        for (; i < 2; i++) {
            for (; j < BLOCK_LENGTH; j++) {
                if (block[i][j] == 0) {
                    return i * BLOCK_LENGTH + j;
                }
            }
        }
        return 200;         //此处定义200表示硬盘无空闲块
    }

    public void showFileInfo(Document f) {
        System.out.println(f.getName() + " " + f.name[0] + f.name[1] + f.name[2] + f.name[3] + " " + f.extendName + " " + f.attribute + " " + f.begin + " " + f.size);
    }

}
